package controlador;

import hbt.HibernateDAO;

import java.util.ArrayList;
import java.util.List;

import util.gestorFecha;
import dominioDAO.CPRGananciaDAO;
import dominioDAO.ListaPreciosDAO;
import dominioDAO.OrdenCompraProveedorDAO;
import dominioDAO.OrdenPedidoClienteDAO;
import dominioDAO.RemitoProveedorDAO;
import dominioEntity.CPRGanancia;
import dominioEntity.ItemCotizacion;
import dominioEntity.ItemListaPrecios;
import dominioEntity.ItemOrdenCompra;
import dominioEntity.ItemRemitoProveedor;
import dominioEntity.OrdenCompraProveedor;
import dominioEntity.OrdenPedidoCliente;
import dominioEntity.Proveedor;
import dominioEntity.RemitoProveedor;
import dominioEntity.Rodamiento;
import dominioTO.ItemRemitoProveedorTO;
import dominioTO.RemitoProveedorTO;


public class CPR {
	private static CPR instancia;

	

	public CPR() {
		super();
		// TODO Auto-generated constructor stub
	}
	public static CPR getInstancia()
	{
		if(instancia==null)
		{
			instancia=new CPR();
		}
		return instancia;
	}
	
	public ItemListaPrecios CalcularPrecioRodamiento(Rodamiento rod)
	{
		List<ItemListaPrecios> aux = ListaPreciosDAO.getInstancia().obtenerMejorLista(rod);
		
		for(ItemListaPrecios item : aux)
		{
			return item;
		}
		
		return null;
	}

	public List<OrdenCompraProveedor> generarOrdenesDeCompraProveedores()
	{		
		List<OrdenPedidoCliente> listaOrdenPedidoCliente = OrdenPedidoClienteDAO.getInstancia().getOrdenPedidoPendientes(OrdenPedidoCliente.Aceptada); 
		
		List<OrdenCompraProveedor> ordenesDeCompraProveedor = new ArrayList<OrdenCompraProveedor>();
		
		//Busco los Items Cotizacion a comprar
		for(OrdenPedidoCliente opCliente:listaOrdenPedidoCliente)
		{
			//Por cada item de la cotizacion lo agrego a la orden de compra
			for(ItemCotizacion itemCotizacion :opCliente.getItemsCotizados())
			{
				ItemListaPrecios itemLista = itemCotizacion.getItemListaPrecio();
				 this.agregarItemAOrdenCompraProveedor(ordenesDeCompraProveedor, itemLista, itemCotizacion.getCantidad(), itemCotizacion);
				 
			}	
		}
		
		
		for(OrdenPedidoCliente op: listaOrdenPedidoCliente)
		{
			op.setEstado(OrdenPedidoCliente.AceptadaPedidoRealizado);
			HibernateDAO.getInstancia().update(op);
		}
		//Persisto la orden
		OrdenCompraProveedorDAO.getInstancia().persistirOrdenesCompraProveedor(ordenesDeCompraProveedor);
		
		
		List<OrdenCompraProveedor> returnOrdenes = new ArrayList<OrdenCompraProveedor>();
		for(OrdenCompraProveedor aux:ordenesDeCompraProveedor )
		{
			returnOrdenes.add(OrdenCompraProveedorDAO.getInstancia().buscarOrdenesCompraProveedor(aux));
		}
		
		return returnOrdenes;
	}
	
	private void agregarItemAOrdenCompraProveedor(List<OrdenCompraProveedor> ordenesDeCompraProveedor, ItemListaPrecios itemLista, Integer cantidad, ItemCotizacion itemCotizacion)
	{
		if(!ordenesDeCompraProveedor.isEmpty())
		{
			//Busco cada orden de compra inicializada por el sistema
			for(OrdenCompraProveedor ordenCompra : ordenesDeCompraProveedor)
			{
				//Busco si existe algun item de la orden de compra ya pedido
				for(ItemOrdenCompra itemOC:ordenCompra.getItemsOC())
				{
					if(itemOC.getItemListaPrecio().getId()==itemLista.getId())
					{
						Integer cantidadTotal = itemOC.getCantidad()+cantidad;
						itemOC.setCantidad(cantidadTotal);
						ordenCompra.agregarItemCotizacion(itemCotizacion);
						return;
					}
					
				}				
			}	
			Proveedor prov =ListaPreciosDAO.getInstancia().buscarProveedorLista(itemLista.getId());
			for(OrdenCompraProveedor ordenCompra : ordenesDeCompraProveedor)
			{
				if(prov.getCuit().equalsIgnoreCase(ordenCompra.getProveedor().getCuit()))
				{
					ItemOrdenCompra itemOC = new ItemOrdenCompra();
					itemOC.setCantidad(cantidad);
					itemOC.setItemListaPrecio(itemLista);
					
					ordenCompra.agregarItem(itemOC);
					ordenCompra.agregarItemCotizacion(itemCotizacion);
					return;
				}
			}
		}
			//Si no existe ningun pedido al proveedor genero una nueva Orden de pedido.
			OrdenCompraProveedor OC = new OrdenCompraProveedor();
			OC.setFechaEmision(gestorFecha.getFechaHoy());
			
			Proveedor provNuevo =ListaPreciosDAO.getInstancia().buscarProveedorLista(itemLista.getId());
			OC.setProveedor(provNuevo);
			
			//Genero el nuevo item de la orden de compra a proveedor
			ItemOrdenCompra itemOCNueva = new ItemOrdenCompra();
			itemOCNueva.setCantidad(cantidad);
			itemOCNueva.setItemListaPrecio(itemLista);
			OC.agregarItem(itemOCNueva);
			OC.agregarItemCotizacion(itemCotizacion);

			//Agrego la nueva orden de compra a la ya inicializada.
			ordenesDeCompraProveedor.add(OC);			
				
	}
	
	public void setNuevoPorcentajeGanancia(Integer i)
	{
		CPRGanancia nuevo = new CPRGanancia ();
		nuevo.setFecha(gestorFecha.getFechaHoy());
		nuevo.setPorcentajeGanancia(i);
		nuevo.setVigente(true);
		
		CPRGanancia viejo=CPRGananciaDAO.getInstancia().getPorcentajeGananciaVigente();
		if(viejo!=null)
		{
			viejo.setVigente(false);
			CPRGananciaDAO.getInstancia().grabar(viejo);
		}
		
		CPRGananciaDAO.getInstancia().grabar(nuevo);
	}
	
	public void persistirRemitoProveedor(RemitoProveedorTO dto)
	{
		RemitoProveedor remito = new RemitoProveedor();
		OrdenCompraProveedor ordenCompraProv = OrdenCompraProveedorDAO.getInstancia().buscarOrdenCompraProveedorPorId(dto.getOrdenCompraProveedor().getIdOC());
		remito.setOrdenCompraProveedor(ordenCompraProv);
		List<ItemRemitoProveedor> items = new ArrayList<ItemRemitoProveedor>();
		for(ItemRemitoProveedorTO itemTO: dto.getItemRemitoProveedor())
		{
			ItemRemitoProveedor itemRemitoProv = new ItemRemitoProveedor();
			itemRemitoProv.setCantidadEntregada(itemTO.getCantidadEntregada());			
			Rodamiento rod = Rodamiento.convertirTO( itemTO.getItemListaPrecio().getRodamiento());
			ItemListaPrecios itemLista = OrdenCompraProveedorDAO.getInstancia().buscarItemLista(dto.getOrdenCompraProveedor().getIdOC(), rod);
			itemRemitoProv.setItemListaPrecio(itemLista);
			items.add(itemRemitoProv);
		}
		remito.setItemRemitoProveedor(items);
		
		RemitoProveedorDAO.getInstancia().grabarRemitoProveedor(remito);
	}


	//Actualiza todos los items a partir del Remito de proveedor
	public void procesarRemitosProveedores() //RECIBIR MERCADERIA
	{
		List<RemitoProveedor> remitosPendientes = RemitoProveedorDAO.getInstancia().buscarRemitoPorEstado(RemitoProveedor.getPendiente());
		
		//Comienzo a Recorrer todos los items en estado pendiente
		for(RemitoProveedor r: remitosPendientes)
		{
			//Busco del Remito, Los item asociados a la OrdenCompraProveedor a la que esta asociada
			List<ItemCotizacion> itemsCotizacion = OrdenCompraProveedorDAO.getInstancia().buscaItemCotizacionOrden(r.getOrdenCompraProveedor().getIdOC());
		
			
			//Recooro los items de cada Remito
			for(ItemRemitoProveedor itemRemito: r.getItemRemitoProveedor())
			{
				//Si el itemRemito ya es 0 no recorro nada
				if(itemRemito.getCantidadEntregada()>0)
				{
					for(ItemCotizacion itemCoti:itemsCotizacion)
					{

						if(itemCoti.getStock()<itemCoti.getCantidad())
						{
							//Si alcanza a cubrir el pedido en su totalidad
							Integer cantidadNecesaria = itemCoti.getCantidad()-itemCoti.getStock();
							
							if(cantidadNecesaria<itemRemito.getCantidadEntregada())
							{
								//Como el if indica que el ItemRemito puede cumplir con la cotizacion agrego stock
								itemCoti.agregarStockRodamiento(cantidadNecesaria);
								//Descuento el stock del Item Remito
								itemRemito.setCantidadEntregada(itemRemito.getCantidadEntregada()-cantidadNecesaria);
							}else{
								//Completo el stock para informar que ya esta disponible
								itemCoti.agregarStockRodamiento(itemRemito.getCantidadEntregada());;
								//Como utiliza todo los rodamientos entregados pongo en 0
								itemRemito.setCantidadEntregada(0);
							}
							
						}
					}	
				}
				
			}
			HibernateDAO.getInstancia().persistList2(itemsCotizacion);			
		}		
		
		for(RemitoProveedor remitoEstado:remitosPendientes)
		{
			remitoEstado.setEstado(RemitoProveedor.getProcesada());
			RemitoProveedorDAO.getInstancia().aceptarRemitoProveedor(remitoEstado.getId(), RemitoProveedor.getProcesada());
		}
		
	}
}
